package savelog;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import com.project.savelog.GameListFragment.GameListListener;

import android.app.Activity;
import android.app.FragmentManager;
import android.os.Bundle;
import java.util.Collections;
import java.util.Map.Entry;

import android.widget.Button;
import android.widget.PopupWindow;
import android.content.Context;
import android.content.SharedPreferences;
import android.support.v4.widget.SlidingPaneLayout.LayoutParams;
import android.view.Gravity;
import android.view.View;
import android.view.LayoutInflater;
import android.view.View.OnClickListener;

/**
 * Title: UpdateActivity class for CSIS 343 Final Project 
 * Description: CS 343 Final Project - UpdateActivity This class will handle pushing and pulling save files
 * 
 * @author Erik Olson
 * @email erik.olson-5@my.uwrf.edu
 * @author Mike Harmon
 * @email michael.harmon@my.uwrf.edu
 * @author Jack Friermuth
 * @email jack.friermuth@my.uwrf.edu
 * @author Luke Vang
 * @email luke.vang@my.uwrf.edu
 * @author Casey Golla
 * @email casey.golla@my.uwrf.edu
 * @date December 4th 2012
 */
public class UpdateActivity extends Activity implements GameListListener {

	public static ArrayList<Games> gameListAZ;
	public static ArrayList<Games> gameListLatest;
	public static ArrayList<Games> gameList;
	public static ArrayList<Saves> selectedSaves;
	public static Games selectedGame;
	public static String pathToBackup;
	public static int currGameSelected;
	private boolean gbaActive, snesActive, segaActive, n64Active, nesActive, useCovers;
	public static ArrayList<String> directories;

	public Button btnUploadAll;
	public Button btnUploadLatest;
	public Button btnDownloadAll;
	
	public FragmentManager fragMan;
	public GameListFragment gListFrag;

	/**
	 * Method to handle creation of activity
	 * @param savedInstanceState :		saved instance variables for activity
	 * @Override
	 */
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.update_layout);
		
		//setting up buttons and their onclick listeners
		btnUploadAll = (Button) findViewById(R.id.upload_all_button);
		btnUploadAll.setOnClickListener(new OnClickListener(){

			@Override
			public void onClick(View v) {
				uploadSelectedGames(true);
			}
			
		});
		
		btnUploadLatest = (Button) findViewById(R.id.upload_lastest_button);
		btnUploadLatest.setOnClickListener(new OnClickListener(){

			@Override
			public void onClick(View v) {
				uploadSelectedGames(false);
			}
			
		});
		
		btnDownloadAll = (Button) findViewById(R.id.download_all_button);
		btnDownloadAll.setOnClickListener(new OnClickListener(){

			@Override
			public void onClick(View v) {
				downloadFromDropbox();
				v.setEnabled(false);
			}
			
		});

		//getting the shared prefs
		getPathToBackupAndSystems();

		fragMan = getFragmentManager();
		
		//selecting all games to be displayed by default
		selectGameListSystem("All", true);
		
		//check if their are any saved variables
		if (savedInstanceState != null) {
			gListFrag = (GameListFragment) fragMan.findFragmentByTag("gListFrag");
			gListFrag.setGameListData(gameListAZ, true);

		} else {
			gListFrag = new GameListFragment();
			gListFrag.setGameListData(gameListAZ, true);

			fragMan.beginTransaction()
					.replace(R.id.gameListFragment, gListFrag, "gListFrag")
					.commit();
		}
	}

	/**
	 * Method implemented by GameListListener
	 * @Override
	 */
	public void onGameSelected(int selectedGameID) {

	}
	
	/**
	 * Method to update the game list fragment
	 * @param updateGameList		the list of games to update
	 */
	public void updateGameListFragment(ArrayList<Games> updateGameList){
		gListFrag = new GameListFragment();			
		gListFrag.setGameListData( updateGameList, true );
		
		fragMan.beginTransaction().replace( R.id.gameListFragment, gListFrag, "gListFrag" ).commit();
	}
	
	/**
	 * Method to get games for a particular system
	 * @param system	  :		the name of the system
	 * @param isOnCreate :		is method called from onCreate?
	 */
	public void selectGameListSystem(String system, boolean isOnCreate){
		gameListAZ = new ArrayList<Games>();
		gameListLatest = new ArrayList<Games>();
		
		if(system == "GBA"){
			gameListAZ = (ArrayList<Games>) MainActivity.data.getGamesOnSystemAZ(5);
			gameListLatest = (ArrayList<Games>) MainActivity.data.getGamesOnSystem(5);
		}
		else if(system == "SNES"){
			gameListAZ = (ArrayList<Games>) MainActivity.data.getGamesOnSystemAZ(1);
			gameListLatest = (ArrayList<Games>) MainActivity.data.getGamesOnSystem(1);
		}
		else if(system == "SEGA"){
			gameListAZ = (ArrayList<Games>) MainActivity.data.getGamesOnSystemAZ(4);
			gameListLatest = (ArrayList<Games>) MainActivity.data.getGamesOnSystem(4);
		}
		else if(system == "N64"){
			gameListAZ = (ArrayList<Games>) MainActivity.data.getGamesOnSystemAZ(2);
			gameListLatest = (ArrayList<Games>) MainActivity.data.getGamesOnSystem(2);
		}
		else if(system == "Nintendo"){
			gameListAZ = (ArrayList<Games>) MainActivity.data.getGamesOnSystemAZ(6);
			gameListLatest = (ArrayList<Games>) MainActivity.data.getGamesOnSystem(6);
		}
		else{
			gameListAZ = (ArrayList<Games>) MainActivity.data.getGamesSortedByGameTitle();
			gameListLatest = (ArrayList<Games>) MainActivity.data.getAllGames();
		}
		Collections.reverse(gameListLatest);
		
		//If we are selecting the system from the PopupWindow (and not from OnCreate),
		if( isOnCreate == false ){
		// then update the GameListFragment with the AZ sorted list of Games
			updateGameListFragment(gameListAZ);
		}
	}
	
	/**
	 * handle the popup window when the system button is clicked
	 * @Override
	 */
	public void onSystemSelected() {
		createSystemPopup();
	}

	/**
	 * Method to handle when the sort AZ button is clicked 
	 * @Override
	 */
	public void onSortAZ() {
		updateGameListFragment(gameListAZ);		
	}

	/**
	 * Method to handle when the sort latest button is clicked
	 * @Override
     */	
	public void onSortLatest() {
		updateGameListFragment(gameListLatest);		
	}
	
	/**
     * Method to handle getting values from shared preferences
     */
	public void getPathToBackupAndSystems(){
		String backupPath = "";
		
		SharedPreferences prefs = this.getSharedPreferences(MainActivity.ACCOUNT_PREFS_NAME, Context.MODE_PRIVATE);
		backupPath = prefs.getString("m_chosenPathDir", "") + "/backup";
		pathToBackup = backupPath;
		
		int setting_layout = prefs.getInt("setting_layout", 0);
		useCovers = false;
		
		if( 0 == setting_layout ) {
			useCovers = true;
		}
		gbaActive = prefs.getBoolean("GBA_CHK", false); 
		snesActive = prefs.getBoolean("SNES_CHK", false); 
		segaActive = prefs.getBoolean("SEGA_CHK", false); 
		n64Active = prefs.getBoolean("N64_CHK", false); 
		nesActive = prefs.getBoolean("NINTENDO_CHK", false);
	}
	
	/**
	 * Creates the PopupWindow for choosing which console
	 * @return null
	 */
	protected void createSystemPopup() {
		//This is to prevent multiple popups on the screen at the same time
		//popupOnScreen = true;
		
		// Inflating the PopupView onto the WebView
		final LayoutInflater layoutInflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		final View popupView = layoutInflater.inflate( R.layout.system_select_layout, null, false );

		// Creating a new PopupWindow to put in the popupView and setting it's
		// parameters, the first WRAP_CONTENT is for the width
		final PopupWindow popupWindow = new PopupWindow(popupView, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);

		// In order to have the Popup dismiss on an outside click, you have to
		// set the backgroundDrawable programmatically and not through the layout .xml
		popupWindow.setFocusable(false);
		popupWindow.setTouchable(true);
		popupWindow.setOutsideTouchable(true);
		popupWindow.setBackgroundDrawable(this.getResources().getDrawable(R.drawable.gamesave_table_box));

		// Finding the console button and setting the onClickListener
		Button buttonAll = (Button) popupView.findViewById(R.id.buttonAll);
		final String stringAll = (String) buttonAll.getText();
		buttonAll.setOnClickListener(new Button.OnClickListener() {
			@Override
			public void onClick(View v) {
					selectGameListSystem( stringAll, false );
					popupWindow.dismiss();
				
			}
		});

		// Finding the console button and setting the onClickListener
		Button buttonGBA = (Button) popupView.findViewById(R.id.buttonGBA);
		final String stringGBA = (String) buttonGBA.getText();
		buttonGBA.setOnClickListener(new Button.OnClickListener() {
			@Override
			public void onClick(View v) {
				selectGameListSystem( stringGBA, false );
				popupWindow.dismiss();
				
			}
		});
		if(gbaActive == false){
			buttonGBA.setVisibility(View.GONE);
		}

		// Finding the console button and setting the onClickListener
		Button buttonSNES = (Button) popupView.findViewById(R.id.buttonSNES);
		final String stringSNES = (String) buttonSNES.getText();
		buttonSNES.setOnClickListener(new Button.OnClickListener() {
			@Override
			public void onClick(View v) {
				selectGameListSystem( stringSNES, false );
				popupWindow.dismiss();
				
			}
		});
		if(snesActive == false){
			buttonSNES.setVisibility(View.GONE);
		}

		// Finding the console button and setting the onClickListener
		Button buttonSEGA = (Button) popupView.findViewById(R.id.buttonSEGA);
		final String stringSEGA = (String) buttonSEGA.getText();
		buttonSEGA.setOnClickListener(new Button.OnClickListener() {
			@Override
			public void onClick(View v) {
				selectGameListSystem( stringSEGA, false );
				popupWindow.dismiss();
				
			}
		});
		if(segaActive == false){
			buttonSEGA.setVisibility(View.GONE);
		}

		// Finding the console button and setting the onClickListener
		Button buttonN64 = (Button) popupView.findViewById(R.id.buttonN64);
		final String stringN64 = (String) buttonN64.getText();
		buttonN64.setOnClickListener(new Button.OnClickListener() {
			@Override
			public void onClick(View v) {
				selectGameListSystem( stringN64, false );
				popupWindow.dismiss();
				
			}
		});
		if(n64Active == false){
			buttonN64.setVisibility(View.GONE);
		}

		// Finding the console button and setting the onClickListener
		Button buttonNES = (Button) popupView.findViewById(R.id.buttonNES);
		final String stringNES = (String) buttonNES.getText();
		buttonNES.setOnClickListener(new Button.OnClickListener() {
			@Override
			public void onClick(View v) {
				selectGameListSystem( stringNES, false );
				popupWindow.dismiss();
				
			}
		});
		if(nesActive == false){
			buttonNES.setVisibility(View.GONE);
		}

		// Posting the Popup in a separate runnable so it waits for all other processes to finish before appearing
		popupView.post(new Runnable() {
			public void run() {
				popupWindow.showAtLocation(popupView, Gravity.CENTER, 0, 0);
			}
		});

	}
	
	/**
	 * Method to update the selected games
	 * @param isAllSaves :		are we updating all games?
	 */
	public void uploadSelectedGames(boolean isAllSaves){
		//setting of variables
		Hashtable<Integer, Boolean> selectedGames = gListFrag.getSelectedGamesHashtable();
		List<Saves> savesForGame = new ArrayList<Saves>();
		SharedPreferences prefs = this.getSharedPreferences(MainActivity.ACCOUNT_PREFS_NAME, Context.MODE_PRIVATE);
		String deviceName = prefs.getString("deviceName", "");
		String dbPath = "/" + deviceName + "/"; 
		
		//getting game
		int gameID;
		Set<Entry<Integer, Boolean>> gameSet = selectedGames.entrySet();	
		Iterator<Entry<Integer, Boolean>> gameSetIter = gameSet.iterator();
		
		//looping through saves updating them
		while(gameSetIter.hasNext()){
			Hashtable.Entry<Integer, Boolean> entry = gameSetIter.next();
			if(entry.getValue() == true){
				gameID = entry.getKey();
				
				if(isAllSaves == true){
					savesForGame = MainActivity.data.getSavesByGameID(gameID);
				}
				else{
					savesForGame.add((Saves) MainActivity.data.getLatestSaveForGame(gameID));
				}
				Upload upload = new Upload(this, MainActivity.mApi, dbPath);
				upload.execute(savesForGame);
			}
			savesForGame = new ArrayList<Saves>();
		}
		
	}
	
	/**
	 * Method to download all files from dropbox
	 */
	public void downloadFromDropbox(){
		directories = MainActivity.list.getDeviceDir();
		for(String directory : directories){
			Download down = new Download(this, MainActivity.mApi, directory, pathToBackup, useCovers);
			down.execute();
		}
	}

}
